package edu.arizona.mindseye;

import static java.awt.GridBagConstraints.BOTH;

import java.awt.GridBagLayout;
import java.io.File;
import java.io.FileFilter;
import java.util.Set;
import java.util.TreeSet;

import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

import edu.arizona.mindseye.database.Database;
import edu.arizona.mindseye.event.Event;
import edu.arizona.mindseye.event.EventListener;
import edu.arizona.mindseye.event.EventManager;
import edu.arizona.mindseye.event.enums.EventType;
import edu.arizona.mindseye.swing.FramePanel;
import edu.arizona.mindseye.swing.GBC;
import edu.arizona.mindseye.swing.MoviePanel;
import edu.arizona.mindseye.swing.StatusPanel;
import edu.arizona.mindseye.swing.VideoControlPanel;

public class Main {
	public static int DEFAULT_MOVIE_WIDTH = 1280;
	public static int DEFAULT_MOVIE_HEIGHT = 720;
	
	private JFrame _frame;
	private Database _database;
	private VideoModel _model;

	private String _directory = "";
	private Set<String> _files;
	private Set<String> _finished;
	
	private JDialog _dialog;
	private JLabel _loading;
	
	public Main(String properties) { 
		EventManager.inst();
		try { 
			PropertiesManager.get().load(properties);
		} catch (Exception e) { 
			JOptionPane.showMessageDialog(null, "Missing properties file contact support!", "Error", JOptionPane.ERROR_MESSAGE);
			return;
		}
		
		_database = new Database();

		// Now initialize the Frame/GUI.
		_frame = new JFrame("UA PSI Annotation");
		_frame.setLayout(new GridBagLayout());
		_frame.getContentPane().add(new MoviePanel(), GBC.makeGBC(0, 0, 2, 1, BOTH, 1, 0));
		_frame.getContentPane().add(new FramePanel(), GBC.makeGBC(0, 1, BOTH, 1, 1));
		_frame.getContentPane().add(new VideoControlPanel(), GBC.makeGBC(0, 2, BOTH, 0, 0));
		_frame.getContentPane().add(new StatusPanel(), GBC.makeGBC(0, 3, 2, 1, BOTH, 1, 0));
		_frame.setSize(1024,768);
	
		_loading = new JLabel("Loading");
		_dialog = new JDialog((JFrame) null, "Loading");
		_dialog.add(_loading);
		_dialog.setSize(300, 200);

		if (Boolean.parseBoolean(PropertiesManager.get().getProperty("firstTime"))) {
			JOptionPane.showMessageDialog(null, "In the next dialog, please select a directory \n" +
					" that contains the movies you would like to annotate.", "Select", JOptionPane.INFORMATION_MESSAGE);
			PropertiesManager.get().setProperty("firstTime", "false");
		}
		
		JFileChooser fileChooser = new JFileChooser(PropertiesManager.get().getProperty("directory"));
		fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		int returnValue = fileChooser.showOpenDialog(null);
		if (returnValue != JFileChooser.APPROVE_OPTION) 
			return;

		PropertiesManager.get().setProperty("directory", fileChooser.getSelectedFile().getParentFile().getPath());
		_directory = fileChooser.getSelectedFile().getPath() + "/";
		getFiles();
		_database.getFinishedMovies();
		_files.removeAll(_database.getFinishedMovies());

		_model = new VideoModel();
		nextMovie();
		
		EventManager.inst().register(EventType.SAVE_SUCCESSFUL, new EventListener() {
			@Override
			public void onEvent(Event e) {
				nextMovie();
			}
		});
	}
	
	private void getFiles() { 
		_files = new TreeSet<String>();
		File dir = new File(_directory);
		File[] files = dir.listFiles(new FileFilter() {
			@Override
			public boolean accept(File file) {
				if (file.getName().endsWith(".mov") ||
					file.getName().endsWith(".mp4") ||
					file.getName().endsWith(".wmv") ||
					file.getName().endsWith(".mpg") ||
					file.getName().endsWith(".mpeg"))
					return true;
				return false;
			} 
		});
		for (File f : files) { 
			_files.add(f.getName());
		}
	}
	
	private void nextMovie() { 
		
		if (_files.size() == 0)
			return;
		
		String movie = _files.iterator().next();
		while (_files.size() > 1 && _database.done(movie)) { 
			_files.remove(movie);
			movie = _files.iterator().next();
		}
		
		if (_files.size() == 0)
			return;

		_frame.setVisible(false);
		
		_loading.setText("Loading next movie -- " + movie);
		_dialog.setVisible(true);
		load(movie);
	}
	
	private void load(final String movie) { 
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				_database.getMovieId(movie);
				_model.load(_directory, movie);

				_dialog.setVisible(false);
				_frame.setVisible(true);
			} 
		});
		
		t.start();
	}

	public static void main(String[] args) { 
		// currently only accepting a single file
		// which contains the properties file.
		String properties = "annotation.properties";
		if (args.length == 1)
			properties = args[0];
		new Main(properties);
	}
}
